package com.amos.muexamcore.core;

import com.amos.core.BaseDTO;
import com.amos.core.BaseEntity;
import com.amos.core.BaseService;
import com.amos.util.PropertiesCopyUtils;
import com.amos.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.List;

/**
 * Copyright © 2018 嘉源锐信. All rights reserved.
 *
 * @Project: mu-exam
 * @ClassName: AbstractService
 * @Package: com.amos.util.core
 * @author: zhuqb
 * @Description:
 * @date: 2020/3/4 0004 下午 17:06
 * @Version: V1.0
 */
public abstract class AbstractService<T extends BaseDTO, E extends BaseEntity> implements BaseService<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractService.class);
    private Class<T> dtoClass;
    private Class<E> entityClass;

    public AbstractService() {
        dtoClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        entityClass = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
    }

    public abstract BaseMapper<E, T> getMapper();

    /**
     * 保存之前的校验
     *
     * @param dto 保存前的dto数据
     */
    public abstract void preValidate(T dto);

    /**
     * 加载附属数据
     *
     * @param id  id
     * @param dto 根据id加载出来的dto数据
     */
    public abstract void appendSubsidiary(String id, T dto);

    /**
     * 条件查询
     *
     * @param dto 查询的条件
     * @return
     */
    @Override
    public List<T> select(T dto) {
        E entity = PropertiesCopyUtils.dto2Entity(dto, entityClass);
        List<E> datas = getMapper().list(entity);
        return PropertiesCopyUtils.entities2Dtos(datas, dtoClass);
    }

    /**
     * 加载
     *
     * @param id id
     * @return
     */
    @Override
    public T load(String id) {
        E entity = getMapper().load(id);
        T dto = PropertiesCopyUtils.entity2Dto(entity, dtoClass);
        this.appendSubsidiary(id, dto);
        return dto;
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    public int logicDeleted(String id) {
        return getMapper().delete(id);
    }

    /**
     * 新增或者修改
     *
     * @param dto
     * @return
     */
    @Override
    public T save(T dto) {
        this.preValidate(dto);
        if (dto.isNew()) {
            dto.setCreateTime(new Date());
            dto.setDelFlag(Boolean.TRUE);
            dto.setModifyTime(new Date());
            dto.setId(StringUtils.generateUuid());
            this.getMapper().insert(PropertiesCopyUtils.dto2Entity(dto, entityClass));
        } else {
            dto.setModifyTime(new Date());
            this.getMapper().update(PropertiesCopyUtils.dto2Entity(dto, entityClass));
        }
        return dto;
    }
}
